package com.jltx.xq.simplewatch.utils;

import android.content.ContentProviderOperation;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.net.Uri;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;

import com.google.gson.reflect.TypeToken;
import com.jltx.xq.simplewatch.base.App;
import com.jltx.xq.simplewatch.db.SimpleWatchContract;
import com.jltx.xq.simplewatch.db.helper.NewsRecordDBHelper;
import com.jltx.xq.simplewatch.db.helper.NewsStateDBHelper;
import com.jltx.xq.simplewatch.news.model.bean.NewsRecord;
import com.jltx.xq.simplewatch.news.model.bean.NewsState;
import com.jltx.xq.simplewatch.news.model.bean.WeChatNews;

import java.util.ArrayList;
import java.util.List;

import cn.jltx.utils.XqLog;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

/**
 * @author jltxseo
 *         Created by junlintianxia on 2017/08/26.
 */

public class SimpleWatchDBDemo {
    public static final String TAG = "CustomProvider";
    private static Uri newRecordUri = SimpleWatchContract.CONTENT_NEWS_RECORD_URI;


    public static void insert(String channel, int page, int time) {

        List<WeChatNews> list = new ArrayList<>();

        WeChatNews weChatNews = new WeChatNews();
        weChatNews.setIsRead(1);
        weChatNews.setHottime("2017-08-22");
        weChatNews.setTitle("写给孩子就要入幼儿园的新妈妈们,page=" + page);
        weChatNews.setDescription("文怡家常菜");
        weChatNews.setPicUrl("https:\\/\\/zxpic.gtimg.com\\/infonew\\/0\\/wechat_pics_-36410626.jpg\\/640");
        weChatNews.setUrl("http://www.baidu.com");
        list.add(weChatNews);

        weChatNews = new WeChatNews();
        weChatNews.setIsRead(1);
        weChatNews.setHottime("2017-08-22");
        weChatNews.setTitle("最高降7万！这些主流中级车都卖成白菜价了！,page=" + page);
        weChatNews.setDescription("12缸汽车");
        weChatNews.setPicUrl("https:\\/\\/zxpic.gtimg.com\\/infonew\\/0\\/wechat_pics_-36410626.jpg\\/640");
        weChatNews.setUrl("http://www.qq.com");
        list.add(weChatNews);

        weChatNews = new WeChatNews();
        weChatNews.setIsRead(1);
        weChatNews.setHottime("2017-08-22");
        weChatNews.setTitle("比林志玲还大的许晴，为何至今无人敢娶？冯小刚这句话解释真到位！,page=" + page);
        weChatNews.setDescription("懂小姐");
        weChatNews.setPicUrl("https:\\/\\/zxpic.gtimg.com\\/infonew\\/0\\/wechat_pics_-36410626.jpg\\/640");
        weChatNews.setUrl("http://www.souhu.com");
        list.add(weChatNews);
        NewsRecordDBHelper.saveNews(channel,page,time,GsonFactoryUtils.providerGson().toJson(list));
        XqLog.d(TAG, "insert uri=" + newRecordUri);
    }

    public static void queryAllItem() {
        Uri newUri = ContentUris.withAppendedId(newRecordUri, 3);
        String[] proj = new String[]{SimpleWatchContract.NewsRecordColumns.ID
                , SimpleWatchContract.NewsRecordColumns.CHANNEL_CODE
                , SimpleWatchContract.NewsRecordColumns.TIME
                , SimpleWatchContract.NewsRecordColumns.PAGE
                , SimpleWatchContract.NewsRecordColumns.DATA};

        Cursor cursor = App.getApp().getContentResolver().query(newUri, proj, null, null, null);
        while (cursor.moveToNext()) {
            XqLog.d(TAG, "id=" + cursor.getInt(cursor.getColumnIndex(SimpleWatchContract.NewsRecordColumns.ID)));
            XqLog.d(TAG, "channel=" + cursor.getString(cursor.getColumnIndex(SimpleWatchContract.NewsRecordColumns.CHANNEL_CODE)));
            XqLog.d(TAG, "page=" + cursor.getInt(cursor.getColumnIndex(SimpleWatchContract.NewsRecordColumns.PAGE)));
            XqLog.d(TAG, "time=" + cursor.getString(cursor.getColumnIndex(SimpleWatchContract.NewsRecordColumns.TIME)));
            XqLog.d(TAG, "data=" + cursor.getString(cursor.getColumnIndex(SimpleWatchContract.NewsRecordColumns.DATA)));
        }
    }

    public static void querySecondItem() {
        String[] proj = new String[]{SimpleWatchContract.NewsRecordColumns.ID
                , SimpleWatchContract.NewsRecordColumns.CHANNEL_CODE
                , SimpleWatchContract.NewsRecordColumns.TIME
                , SimpleWatchContract.NewsRecordColumns.PAGE
                , SimpleWatchContract.NewsRecordColumns.DATA};
        String selection = SimpleWatchContract.NewsRecordColumns.DATA + " =? ";
        String[] selectionArg = new String[]{"内容2"};
        Cursor cursor = App.getApp().getApplicationContext().getContentResolver().query(newRecordUri, proj, null, null, SimpleWatchContract.NewsRecordColumns.ID + " DESC");
        while (cursor.moveToNext()) {
            XqLog.d(TAG, "id=" + cursor.getInt(cursor.getColumnIndex(SimpleWatchContract.NewsRecordColumns.ID)));
            XqLog.d(TAG, "channel=" + cursor.getString(cursor.getColumnIndex(SimpleWatchContract.NewsRecordColumns.CHANNEL_CODE)));
            XqLog.d(TAG, "page=" + cursor.getInt(cursor.getColumnIndex(SimpleWatchContract.NewsRecordColumns.PAGE)));
            XqLog.d(TAG, "time=" + cursor.getString(cursor.getColumnIndex(SimpleWatchContract.NewsRecordColumns.TIME)));
            XqLog.d(TAG, "data=" + cursor.getString(cursor.getColumnIndex(SimpleWatchContract.NewsRecordColumns.DATA)));
        }
    }

    /**
     * 通过ContentResolver,将MyProvider中的值全部删除
     */
    public static void deleteAll() {
        Log.d(TAG, "delete all value!");
        App.getApp().getContentResolver().delete(newRecordUri, null, null);
    }

    public static void deleteItem() {
        Uri newUri = ContentUris.withAppendedId(newRecordUri, 20);
        App.getApp().getContentResolver().delete(newUri, null, null);
    }

    public static void updateItem() {
        Uri newUri = ContentUris.withAppendedId(newRecordUri, 34);
        ContentValues cv = new ContentValues();
        cv.put(SimpleWatchContract.NewsRecordColumns.DATA, "内容内容111111111111111");

        App.getApp().getContentResolver().update(newUri, cv, null, null);
    }

    /**
     * 批量操作
     */
    public static void applyItem() {
        ArrayList<ContentProviderOperation> ops =
                new ArrayList<ContentProviderOperation>();
        ops.add(
                ContentProviderOperation.newInsert(newRecordUri)
                        .withValue(SimpleWatchContract.NewsRecordColumns.CHANNEL_CODE, "someAccountType")
                        .withValue(SimpleWatchContract.NewsRecordColumns.PAGE, 111111)
                        .withValue(SimpleWatchContract.NewsRecordColumns.TIME, 111111)
                        .withValue(SimpleWatchContract.NewsRecordColumns.DATA, "内容2222222222")
                        .withYieldAllowed(true)
                        .build());

        ops.add(
                ContentProviderOperation.newInsert(newRecordUri)
                        .withValue(SimpleWatchContract.NewsRecordColumns.CHANNEL_CODE, "someAccountType")
                        .withValue(SimpleWatchContract.NewsRecordColumns.PAGE, 111111)
                        .withValue(SimpleWatchContract.NewsRecordColumns.TIME, 111111)
                        .withValue(SimpleWatchContract.NewsRecordColumns.DATA, "内容2222222222")
                        .withYieldAllowed(true)
                        .build());


        ops.add(
                ContentProviderOperation.newInsert(newRecordUri)
                        .withValue(SimpleWatchContract.NewsRecordColumns.CHANNEL_CODE, "someAccountType")
                        .withValue(SimpleWatchContract.NewsRecordColumns.PAGE, 111111)
                        .withValue(SimpleWatchContract.NewsRecordColumns.TIME, 111111)
                        .withValue(SimpleWatchContract.NewsRecordColumns.DATA, "内容2222222222")
                        .withYieldAllowed(true)
                        .build());

        ops.add(
                ContentProviderOperation.newInsert(newRecordUri)
                        .withValue(SimpleWatchContract.NewsRecordColumns.CHANNEL_CODE, "someAccountType")
                        .withValue(SimpleWatchContract.NewsRecordColumns.PAGE, 111111)
                        .withValue(SimpleWatchContract.NewsRecordColumns.TIME, 111111)
                        .withValue(SimpleWatchContract.NewsRecordColumns.DATA, "内容2222222222")
                        .withYieldAllowed(true)
                        .build());


        ops.add(
                ContentProviderOperation.newInsert(newRecordUri)
                        .withValue(SimpleWatchContract.NewsRecordColumns.CHANNEL_CODE, "someAccountType")
                        .withValue(SimpleWatchContract.NewsRecordColumns.PAGE, 111111)
                        .withValue(SimpleWatchContract.NewsRecordColumns.TIME, 111111)
                        .withValue(SimpleWatchContract.NewsRecordColumns.DATA, "内容2222222222")
                        .withYieldAllowed(true)
                        .build());


        ops.add(
                ContentProviderOperation.newInsert(newRecordUri)
                        .withValue(SimpleWatchContract.NewsRecordColumns.CHANNEL_CODE, "someAccountType")
                        .withValue(SimpleWatchContract.NewsRecordColumns.PAGE, 111111)
                        .withValue(SimpleWatchContract.NewsRecordColumns.TIME, 111111)
                        .withValue(SimpleWatchContract.NewsRecordColumns.DATA, "内容2222222222")
                        .withYieldAllowed(true)
                        .build());


        ops.add(
                ContentProviderOperation.newInsert(newRecordUri)
                        .withValue(SimpleWatchContract.NewsRecordColumns.CHANNEL_CODE, "someAccountType")
                        .withValue(SimpleWatchContract.NewsRecordColumns.PAGE, 111111)
                        .withValue(SimpleWatchContract.NewsRecordColumns.TIME, 111111)
                        .withValue(SimpleWatchContract.NewsRecordColumns.DATA, "内容2222222222")
                        .withYieldAllowed(true)
                        .build());

        ops.add(
                ContentProviderOperation.newInsert(newRecordUri)
                        .withValue(SimpleWatchContract.NewsRecordColumns.CHANNEL_CODE, "someAccountType")
                        .withValue(SimpleWatchContract.NewsRecordColumns.PAGE, 111111)
                        .withValue(SimpleWatchContract.NewsRecordColumns.TIME, 111111)
                        .withValue(SimpleWatchContract.NewsRecordColumns.DATA, "内容2222222222")
                        .withYieldAllowed(true)
                        .build());

        try {
            App.getApp().getApplicationContext().getContentResolver().
                    applyBatch(newRecordUri.getAuthority(), ops);
        } catch (RemoteException e) {
            // do s.th.
        } catch (OperationApplicationException e) {
            // do s.th.
        }
    }

    /**
     * rxjava + contentprovider
     *
     * @param uri
     */
    public static void queryAllItemRx(final Uri uri) {
        Observable.create(new ObservableOnSubscribe<List<NewsRecord>>() {
            @Override
            public void subscribe(ObservableEmitter<List<NewsRecord>> e) throws Exception {
                String[] proj = new String[]{SimpleWatchContract.NewsRecordColumns.ID
                        , SimpleWatchContract.NewsRecordColumns.CHANNEL_CODE
                        , SimpleWatchContract.NewsRecordColumns.TIME
                        , SimpleWatchContract.NewsRecordColumns.PAGE
                        , SimpleWatchContract.NewsRecordColumns.DATA};
                Cursor cursor = null;
                try {
                    cursor = App.getApp().getApplicationContext().getContentResolver().query(uri, proj, null, null, null);
                    List<NewsRecord> result = new ArrayList<NewsRecord>();
                    while (cursor.moveToNext()) {
                        NewsRecord newRecord = new NewsRecord();
                        newRecord.setChannel(cursor.getString(cursor.getColumnIndex(SimpleWatchContract.NewsRecordColumns.CHANNEL_CODE)));
                        newRecord.setPage(cursor.getInt(cursor.getColumnIndex(SimpleWatchContract.NewsRecordColumns.PAGE)));
                        newRecord.setTime(cursor.getInt(cursor.getColumnIndex(SimpleWatchContract.NewsRecordColumns.TIME)));
                        newRecord.setData(cursor.getString(cursor.getColumnIndex(SimpleWatchContract.NewsRecordColumns.DATA)));
                        result.add(newRecord);
                    }
                    e.onNext(result);
                    e.onComplete();
                } finally {
                    if (cursor != null) cursor.close();
                }

            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<List<NewsRecord>>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(List<NewsRecord> newsRecords) {
                        if (newsRecords != null) {
                            for (NewsRecord newRecord : newsRecords) {
                                XqLog.d(TAG, "--------------------");
                                XqLog.d(TAG, "channel=" + newRecord.getChannel());
                                XqLog.d(TAG, "page=" + newRecord.getPage());
                                XqLog.d(TAG, "time=" + newRecord.getTime());
                                XqLog.d(TAG, "data=" + newRecord.getData());
                                XqLog.d(TAG, "--------------------");
                            }
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        XqLog.d(TAG, "--------------------onError" + e);
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }


    public static void queryMaxItemRx(final String channel) {
        Observable.create(new ObservableOnSubscribe<NewsRecord>() {
            @Override
            public void subscribe(ObservableEmitter<NewsRecord> e) throws Exception {
                NewsRecord newsRecord = NewsRecordDBHelper.getLastNewsRecordNoNull(channel);
                e.onNext(newsRecord);
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<NewsRecord>() {
                    @Override
                    public void accept(@NonNull NewsRecord newsRecord) throws Exception {
                        if (newsRecord != null && !TextUtils.isEmpty(newsRecord.getData())) {
                            XqLog.d(TAG, "--------------------");
                            XqLog.d(TAG, "channel=" + newsRecord.getChannel());
                            XqLog.d(TAG, "page=" + newsRecord.getPage());
                            XqLog.d(TAG, "time=" + newsRecord.getTime());
                            XqLog.d(TAG, "data=" + newsRecord.getData());
                            XqLog.d(TAG, "--------------------");
                        } else {
                            XqLog.d(TAG, "newsRecord  had no data");
                        }
                    }
                })
                .observeOn(Schedulers.computation())
                .map(new Function<NewsRecord, List<WeChatNews>>() {
                    @Override
                    public List<WeChatNews> apply(@NonNull NewsRecord newsRecord) throws Exception {
                        List<WeChatNews> result = new ArrayList<WeChatNews>();
                        if (newsRecord != null && !TextUtils.isEmpty(newsRecord.getData())) {
                            try {
                                result = GsonFactoryUtils.providerGson().fromJson(newsRecord.getData(), new TypeToken<List<WeChatNews>>() {
                                }.getType());
                            } catch (Exception e) {
                                XqLog.d(TAG, "parser erro for news record");
                            }
                        }
                        return result;
                    }
                })
                .observeOn(Schedulers.io())
                .map(new Function<List<WeChatNews>, List<WeChatNews>>() {
                    @Override
                    public List<WeChatNews> apply(@NonNull List<WeChatNews> weChatNewsList) throws Exception {
                        if(weChatNewsList != null){
                            WeChatNews weChatNews = null;
                            for (int i=0; i < weChatNewsList.size(); i++){
                                weChatNews = weChatNewsList.get(i);
                                NewsState newsState = NewsStateDBHelper.getNewsState(channel,NewsStateUtils.convertWetChatNewsStateKey(weChatNews));
                                if(newsState != null){
                                    weChatNews.setIsRead(newsState.getIs_read());
                                }
                            }
                        }
                        return weChatNewsList;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<List<WeChatNews>>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(List<WeChatNews> weChatNewsList) {
                        if (weChatNewsList != null && weChatNewsList.size() > 0) {
                            for (WeChatNews weChatNews : weChatNewsList) {
                                XqLog.d(TAG, "--------------------");
                                XqLog.d(TAG, "title=" + weChatNews.getTitle());
                                XqLog.d(TAG, "url=" + weChatNews.getUrl());
                                XqLog.d(TAG, "read=" + weChatNews.getIsRead());
                                XqLog.d(TAG, "--------------------");
                            }
                        } else {
                            XqLog.d(TAG, "onNext has no news");
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        XqLog.d(TAG, "--------------------onError" + e);
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }


    public static void queryItemRx(final String channel,final int page) {
        Observable.create(new ObservableOnSubscribe<NewsRecord>() {
            @Override
            public void subscribe(ObservableEmitter<NewsRecord> e) throws Exception {
                NewsRecord newsRecord = NewsRecordDBHelper.getNewsRecordNoNull(channel,page);
                e.onNext(newsRecord);
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<NewsRecord>() {
                    @Override
                    public void accept(@NonNull NewsRecord newsRecord) throws Exception {
                        if (newsRecord != null && !TextUtils.isEmpty(newsRecord.getData())) {
                            XqLog.d(TAG, "--------------------");
                            XqLog.d(TAG, "channel=" + newsRecord.getChannel());
                            XqLog.d(TAG, "page=" + newsRecord.getPage());
                            XqLog.d(TAG, "time=" + newsRecord.getTime());
                            XqLog.d(TAG, "data=" + newsRecord.getData());
                            XqLog.d(TAG, "--------------------");
                        } else {
                            XqLog.d(TAG, "newsRecord  had no data");
                        }
                    }
                })
                .observeOn(Schedulers.computation())
                .map(new Function<NewsRecord, List<WeChatNews>>() {
                    @Override
                    public List<WeChatNews> apply(@NonNull NewsRecord newsRecord) throws Exception {
                        List<WeChatNews> result = new ArrayList<WeChatNews>();
                        if (newsRecord != null && !TextUtils.isEmpty(newsRecord.getData())) {
                            try {
                                result = GsonFactoryUtils.providerGson().fromJson(newsRecord.getData(), new TypeToken<List<WeChatNews>>() {
                                }.getType());
                            } catch (Exception e) {
                                XqLog.d(TAG, "parser erro for news record");
                            }
                        }
                        return result;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<List<WeChatNews>>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(List<WeChatNews> weChatNewsList) {
                        if (weChatNewsList != null && weChatNewsList.size() > 0) {
                            for (WeChatNews weChatNews : weChatNewsList) {
                                XqLog.d(TAG, "--------------------");
                                XqLog.d(TAG, "title=" + weChatNews.getTitle());
                                XqLog.d(TAG, "--------------------");
                            }
                        } else {
                            XqLog.d(TAG, "onNext has no news");
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        XqLog.d(TAG, "--------------------onError" + e);
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    /**
     *插入新闻状态
     */
    public static void insertNewsStateRx(String channel) {
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                NewsStateDBHelper.addOrUpdateNewsState(channel, "http://www.baidu.com", 1, 0);
                NewsStateDBHelper.addOrUpdateNewsState(channel, "http://www.qq.com", 0, 0);
                NewsStateDBHelper.addOrUpdateNewsState(channel, "http://www.souhu.com", 1, 0);
                e.onNext(0);
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer integer) {
                        XqLog.d(TAG, "onNext");
                    }

                    @Override
                    public void onError(Throwable e) {
                        XqLog.d(TAG, "--------------------onError" + e);
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    /**
     * 通过channel和key获取新闻状态
     * @param channel
     * @param key
     */
    public static void queryNewsStateRx(String channel, String key) {
        Observable.create(new ObservableOnSubscribe<NewsState>() {
            @Override
            public void subscribe(ObservableEmitter<NewsState> e) throws Exception {
                NewsState newsState = NewsStateDBHelper.getNewsStateNoNull(channel,key);
                e.onNext(newsState);
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<NewsState>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(NewsState newsState) {
                        if(newsState != null){
                            XqLog.d(TAG, "--------------------");
                            XqLog.d(TAG, "channel=" + newsState.getChannel());
                            XqLog.d(TAG, "key=" + newsState.getKey());
                            XqLog.d(TAG, "isRead=" + newsState.getIs_read());
                            XqLog.d(TAG, "isDel=" + newsState.getIs_del());
                            XqLog.d(TAG, "--------------------");
                        }
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
}
